
// This file is part of the mstp-lib library, available at http://code.google.com/p/mstp-lib/ 
// Copyright (c) 2011-2014 Adrian Gostin, distributed under the GNU General Public License v3.

#ifndef MSTP_BPDU_H
#define MSTP_BPDU_H

#include "base_types.h"
#include "stp.h"

// 14.2.1
enum BPDU_PORT_ROLE
{
	BPDU_PORT_ROLE_MASTER = 0,
	BPDU_PORT_ROLE_UNKNOWN = 0,
	BPDU_PORT_ROLE_ALT_BACKUP = 1,
	BPDU_PORT_ROLE_ROOT = 2,
	BPDU_PORT_ROLE_DESIGNATED = 3,
};

// 14.6
union BPDU_FLAGS
{
	struct
	{
		unsigned char Tc		: 1;
		unsigned char Proposal	: 1;
		unsigned char PortRole	: 2;
		unsigned char Learning	: 1;
		unsigned char Forwarding: 1;
		unsigned char Agreement	: 1;
		unsigned char TcAck 	: 1;
	} asCist;
	
	struct
	{
		unsigned char Tc		: 1;
		unsigned char Proposal	: 1;
		unsigned char PortRole	: 2;
		unsigned char Learning	: 1;
		unsigned char Forwarding: 1;
		unsigned char Agreement	: 1;
		unsigned char Master	: 1;
	} asMsti;
	
	struct
	{
		unsigned char Tc		: 1;
		unsigned char Proposal	: 1;
		unsigned char PortRole	: 2;
		unsigned char Learning	: 1;
		unsigned char Forwarding: 1;
		unsigned char Agreement	: 1;
	} asCistOrMsti;
};


struct MSTI_CONFIG_MESSAGE
{
	BPDU_FLAGS	flags;
	BRIDGE_ID	RegionalRootId;
	INV_UINT4	InternalRootPathCost;

	// Bits 5 through 8 of Octet 14 convey the value of the Bridge Identifier Priority for this MSTI. Bits 1
	// through 4 of Octet 14 shall be transmitted as 0, and ignored on receipt.
	unsigned char BridgePriority;

	// Bits 5 through 8 of Octet 15 convey the value of the Port Identifier Priority for this MSTI. Bits 1
	// through 4 of Octet 15 shall be transmitted as 0, and ignored on receipt.
	unsigned char PortPriority;

	unsigned char RemainingHops;

	void Dump (BRIDGE* bridge, int port, int tree) const;
};

// ============================================================================

struct BPDU_HEADER
{
	INV_UINT2 protocolId;
	unsigned char protocolVersionId;
	unsigned char bpduType;
};

// ============================================================================

// 13.7
struct MST_CONFIG_ID
{
	unsigned char ConfigurationIdentifierFormatSelector;// 1)
	char ConfigurationName [32];						// 2)
	INV_UINT2 RevisionLevel;							// 3)
	unsigned char ConfigurationDigest [16];				// 4)
	
	bool operator== (const MST_CONFIG_ID& rhs) const;	
	void Dump (BRIDGE* bridge, int port, int tree) const;
};

// ============================================================================

struct MSTP_BPDU : public BPDU_HEADER
{
	BPDU_FLAGS	cistFlags;				// octet 5
	
	BRIDGE_ID	cistRootId;				// octets 6 to 13
	INV_UINT4	cistExternalPathCost;	// octets 14 to 17
	BRIDGE_ID	cistRegionalRootId;		// octets 18 to 25
	PORT_ID		cistPortId;				// octets 26 to 27
	
	INV_UINT2	MessageAge;		// octets 28 to 29
	INV_UINT2	MaxAge;			// octets 30 to 31
	INV_UINT2	HelloTime;		// octets 32 to 33
	INV_UINT2	ForwardDelay;	// octets 34 to 35
	
	unsigned char Version1Length;
	INV_UINT2 Version3Length;
	
	MST_CONFIG_ID	mstConfigId;
	
	INV_UINT4		cistInternalRootPathCost;
	BRIDGE_ID		cistBridgeId;
	
	unsigned char	cistRemainingHops;
	
	// MSTI_CONFIG_MESSAGE mstiConfigMessages [0];
};

// ============================================================================

enum VALIDATED_BPDU_TYPE
{
	VALIDATED_BPDU_TYPE_UNKNOWN,
	VALIDATED_BPDU_TYPE_STP_CONFIG,
	VALIDATED_BPDU_TYPE_STP_TCN,
	VALIDATED_BPDU_TYPE_RST,
	VALIDATED_BPDU_TYPE_MST
};

enum VALIDATED_BPDU_TYPE MSTP_GetValidatedBpduType (const unsigned char* _bpdu, unsigned int bpduSize);

BPDU_PORT_ROLE GetBpduPortRole (STP_PORT_ROLE role);

void DumpMstpBpdu (BRIDGE* bridge, int port, int tree, const MSTP_BPDU* bpdu);
void DumpRstpBpdu (BRIDGE* bridge, int port, int tree, const MSTP_BPDU* bpdu);

// ============================================================================

#endif
